package com.cuotoniu.lazybug.core.config.data;

import java.util.Map.Entry;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.cfg.ImprovedNamingStrategy;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import com.cuotoniu.lazybug.common.util.PropertiesUtil;
import com.cuotoniu.lazybug.common.util.StringTools;

/**
 * initialization:Data Persistence setting
 * 
 * @author huanglj
 *
 */
@Configuration
public class LazyBugDataConfig {

	/**
	 * set the match method by the transaction interceptor
	 * 
	 * @return
	 */
	@Bean public BeanNameAutoProxyCreator beanNameAutoProxyCreator(){
		BeanNameAutoProxyCreator proxy = new BeanNameAutoProxyCreator();
		proxy.setBeanNames(new String[]{"*Service"});
		proxy.setInterceptorNames(new String[]{"transactionInterceptor"});
		proxy.setProxyTargetClass(true);
		return proxy;
	}
	
	/**
	 * set the interceptor with the transaction
	 * 
	 * @return
	 */
	@Bean(name="transactionInterceptor") public TransactionInterceptor transactionInterceptor(){
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionManager(transactionManager());
		interceptor.setTransactionAttributes(this.interceptorProperties());
		return interceptor;
	}
	
	/**
	 * define the transaction manager 
	 * 
	 * @return
	 */
	@Bean public HibernateTransactionManager transactionManager() {    
        HibernateTransactionManager txManager = new HibernateTransactionManager();    
        txManager.setSessionFactory(this.alertsSessionFactory().getObject());   
        return txManager;    
    }
    
	/**
	 * create the session by the data source
	 * 
	 * @return
	 */
	@Bean(name="sessionFactory") public LocalSessionFactoryBean alertsSessionFactory() {    
		LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();    
        sessionFactoryBean.setDataSource(dataSource());    
        /**sessionFactoryBean.setNamingStrategy(new ImprovedNamingStrategy());*/
        sessionFactoryBean.setHibernateProperties(hProps());  
        sessionFactoryBean.setPackagesToScan(new String[]{"com.cuotoniu.lazybug.model"});
        return sessionFactoryBean;
    }
    
	/**
	 * Interceptor parms setting
	 * 
	 * @return
	 */
	private Properties interceptorProperties(){
		Properties p = new Properties();
		PropertiesUtil.initialization(INIT_PROPERTIES_PATH + "transaction_match.properties");
    	try {
			for (Entry<Object, Object> m : PropertiesUtil.getProperties().entrySet()) {
				if (!StringTools.isEmpty(m.getValue().toString().trim())) {
					p.put(m.getKey().toString().trim(), m.getValue().toString().trim());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
        return p; 
	}
	
	/**
	 * Get the data connection source 
	 * 
	 * @return
	 */
    private DataSource dataSource() {
    	BasicDataSource source = new BasicDataSource();
    	PropertiesUtil.initialization(INIT_PROPERTIES_PATH + "data_connection.properties");
        source.setDriverClassName(PropertiesUtil.getValue("clazzname"));  
        source.setUrl(PropertiesUtil.getValue("url"));  
        source.setUsername(PropertiesUtil.getValue("username"));
        source.setPassword(PropertiesUtil.getValue("password"));
        return source;
    }
	
    /**
     * Hibernate setting(key,value)
     * 
     * @return
     */
	private Properties hProps() {  
        Properties p = new Properties();
        PropertiesUtil.initialization(INIT_PROPERTIES_PATH + "hibernate_config.properties");
    	try {
			for (Entry<Object, Object> m : PropertiesUtil.getProperties().entrySet()) {
				if (!StringTools.isEmpty(m.getValue().toString().trim())) {
					p.put(m.getKey().toString().trim(), m.getValue().toString().trim());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
        return p;  
    }
	
	private static final String INIT_PROPERTIES_PATH = "com/cuotoniu/lazybug/core/config/properties/";
}
